home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Mac-Source 1994 July
/
Mac-Source_July_1994.iso
/
C and C++
/
Libraries
/
CDragAcrossTable 1.0b1
/
CDragAcrossTask.c
< prev
next >
Wrap
Text File
|
1993-11-04
|
10KB
|
350 lines
/******************************************************************************
CDragAcrossTask.c
AUTHOR: Andrew_Gilmartin@Brown.Edu
MODIFIED: 93-11-04
This global mouse task is used in conjunction with a CDragAcrossTable to
provide the user feedback while selecting the boundaries along which to
move the selected cells or place a new object/cell.
Copyright (C) 1993 by Brown University. All rights reserved.
Permission is granted to any individual or institution to use, copy,
or redistribute the binary version of this software and its
documentation provided this notice and the copyright notices are
retained. Permission is granted to any individual or non-profit
institution to use, copy, modify, or redistribute the source files
of this software provided this notice and the copyright notices are
retained. This software may not be distributed for profit, either
in original form or in derivative works, nor can the source be
distributed to other than an individual or a non-profit institution.
Any individual or group interested in seeing and/or using these
source files but who are prevented from doing so by the above
constraints should contact Don Wolfe, Vice-President for Computer
Systems at Brown University, (401) 863-7247, for possible
software licensing of the source developed at Brown.
Brown University and Andrew James Gilmartin make no representations
about the suitability of this software for any purpose.
BROWN UNIVERSITY AND ANDREW JAMES GILMARTIN GIVE NO WARRANTY, EITHER
EXPRESS OR IMPLIED, FOR THE PROGRAM AND/OR DOCUMENTATION PROVIDED,
INCLUDING, WITHOUT LIMITATION, WARRANTY OF MERCHANTABILITY AND
WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE.
******************************************************************************/
#include "ForgetRgn.h"
#include "CDragAcrossTable.h"
#include "CDragAcrossTask.h"
/******************************************************************************
IDragTable
Initialize the task.
******************************************************************************/
void CDragAcrossTask::IDragAcrossTask
( CDragAcrossTable* aTable
, RgnHandle aSelectionRgn
, short aNameIndex )
{
IGlobalMouseTask( aNameIndex );
itsFromTable = itsToTable = aTable;
itsSelectionRgn = aSelectionRgn;
isSelectionRgnVisible = FALSE;
} /* IDragAcrossTask */
/******************************************************************************
Dispose
Dispose of the drag region and then the rest.
******************************************************************************/
void CDragAcrossTask::Dispose( void )
{
ForgetRgn( itsSelectionRgn );
inherited::Dispose();
} /* Dispose */
/******************************************************************************
BeginTracking
Begin tracking the mouse.
******************************************************************************/
void CDragAcrossTask::BeginTracking( Point startPt )
{
Boundary hitBoundaries;
FindHitBoundaries( itsFromTable, startPt, &hitBoundaries );
itsToBoundaries = hitBoundaries;
itsToTable->Prepare();
itsToTable->SelectBoundaries( itsToBoundaries );
DrawSelectionRgn( TRUE );
} /* BeginTracking */
/******************************************************************************
KeepTracking
The code here is a mixture of screen updating and hit finding. The logical
sequence is
hide the selection region,
deselect the previous boundaries,
find the hit table,
find the hit boundaries,
select the current boundaries, and then
draw the selection region.
However, following this sequence in order does a log of drawing and makes
for a very flickering screen. So the logical sequence is coded to minimize
the amount of screen redraw. It does work but it is really ugly.
******************************************************************************/
void CDragAcrossTask::KeepTracking( Point currPt, Point prevPt, Point startPt )
{
CDragAcrossTable* hitTable;
Boundary hitBoundaries;
Boolean hideBoundary;
Boolean showBoundary;
Boolean moveSelection;
Boolean hideSelection;
Boolean showSelection;
Boolean autoScrolled;
/* Do we have to un-draw the previous boundaries? */
hitTable = FindHitTable( currPt );
if ( hitTable )
{
FindHitBoundaries( hitTable, currPt, &hitBoundaries );
autoScrolled = AutoScroll( hitTable, currPt );
}
else
{
hitBoundaries = kEmptyBoundary;
}
/* Figure out what needs to be drawn */
hideBoundary = itsToTable != NULL && itsToTable != hitTable;
showBoundary = hitTable != NULL
&& ( itsToTable != hitTable || ! EqualPt( itsToBoundaries, hitBoundaries ) );
moveSelection = ! EqualPt( currPt, prevPt );
hideSelection = moveSelection || showBoundary || hideBoundary;
showSelection = autoScrolled || ! hideSelection;
if ( hideSelection )
DrawSelectionRgn( FALSE );
if ( hideBoundary )
{
itsToTable->Prepare();
itsToTable->SelectBoundaries( kEmptyBoundary );
}
if ( showBoundary )
{
hitTable->Prepare();
hitTable->SelectBoundaries( hitBoundaries );
}
if ( moveSelection )
OffsetRgn( itsSelectionRgn, currPt.h - prevPt.h, currPt.v - prevPt.v );
if ( showSelection )
DrawSelectionRgn( TRUE );
itsToTable = hitTable;
itsToBoundaries = hitBoundaries;
// if ( autoScrolled )
// {
// long ticks;
// Delay( PAGE_DELAY, &ticks );
// }
} /* KeepTracking */
/******************************************************************************
EndTracking
Notify the CDragAcrossTable should the user have selected a boundary.
******************************************************************************/
void CDragAcrossTask::EndTracking( Point currPt, Point prevPt, Point startPt )
{
/* Hide and dispose of the selection region */
DrawSelectionRgn( FALSE );
if ( itsToTable != NULL )
{
itsToTable->SelectBoundaries( kEmptyBoundary );
itsFromTable->MoveSelection( itsToTable, itsToBoundaries );
}
} /* EndTracking */
/******************************************************************************
DrawSelectionRgn
Draw the selection region. Since this method is used to both show and hide
the region, isSelectionRgnVisible keeps track of when the region should
really be draw.
******************************************************************************/
void CDragAcrossTask::DrawSelectionRgn( Boolean showRgn )
{
/* Is the visability changing? */
if ( isSelectionRgnVisible != showRgn )
{
PenState penState;
/* Draw on the desktop */
gDesktop->Prepare();
GetPenState( &penState );
PenPat( gray );
PenMode( srcXor );
FrameRgn( itsSelectionRgn );
SetPenState( &penState );
/* Remember its visability */
isSelectionRgnVisible = showRgn;
}
} /* DrawSelectionRgn */
/******************************************************************************
FindHitTable
Finding the drag table is similar to dispatching the cursor. Infact, the
code below is taken from DispatchCursor() and friends. Given a point in
global coordinates first find the enclosing window and then find the
sub-view that is a CDragAcrossTable.
(There should be some means of finding not just a CDragAcrossTable, but a
particular subclass. This could be done by keeping a list of tables to
check. At the end of FindHitTable() it would check that the table found
is amoung the listed tables.)
******************************************************************************/
CDragAcrossTable* CDragAcrossTask::FindHitTable( Point mousePt )
{
WindowPtr macWindow;
CView* hitView;
/* Which Macintosh window? */
if ( FindWindow( mousePt, &macWindow ) != inContent )
return NULL;
/* Is it a TCL window? */
if ( ((WindowPeek) macWindow)->windowKind != OBJ_WINDOW_KIND )
return NULL;
/* Find sub-view that is a CDragAcrossTable */
hitView = (CWindow*) GetWRefCon( macWindow );
hitView->Prepare(); // Use Window's port and coords
GlobalToLocal( &mousePt ); // Convert mouse location in event
do
{
hitView = hitView->FindSubview(mousePt);
} while ( hitView != NULL && ! member( hitView, CDragAcrossTable ) );
/* Done */
return (CDragAcrossTable*) hitView;
} /* FindHitTable */
/******************************************************************************
FindHitBoundaries
A utility method to convert the given point from global to the table's
local coordinates and return info on the boundaries hit.
******************************************************************************/
void CDragAcrossTask::FindHitBoundaries
( CDragAcrossTable* aTable
, Point hitPt
, Boundary* hitBoundary )
{
LongPt tablePt;
aTable->Prepare();
GlobalToLocal( &hitPt );
aTable->QDToFrame( hitPt, &tablePt );
aTable->FindBoundaries( &tablePt, hitBoundary );
} /* FindHitBoundaries */
/******************************************************************************
AutoScroll
A utility method to convert the given point from global to the table's
local coordinates and auto-scroll if necessary. The selection region is
hidden if scrolling is to occure.
******************************************************************************/
Boolean CDragAcrossTask::AutoScroll( CDragAcrossTable* aTable, Point hitPt )
{
LongPt tablePt;
aTable->Prepare();
GlobalToLocal( &hitPt );
aTable->QDToFrame( hitPt, &tablePt );
if ( aTable->ShouldScroll( &tablePt, NULL ) )
{
DrawSelectionRgn( FALSE );
return aTable->AutoScroll( &tablePt );
}
return FALSE;
} /* AutoScroll */